import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.xml.sax.helpers.AttributesImpl;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;

public class Main {


    private static String[] tables = new String[]{
            "dianjia_rms_purchaseorder",
            "dianjia_rms_purchaseorderitem",
            "dianjia_rms_storestock",
            "",
            "",
            ""
    };


    public static void main(String[] args) throws Exception {

        //1、创建SAXTransformerFactory实例
        SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        //2、创建TransformerHandler实例
        TransformerHandler handler = factory.newTransformerHandler();
        //3、创建Transformer实例
        Transformer transformer = handler.getTransformer();
        //4、设置输出的xml属性，encoding为编码，indent是确保输出的xml文件能够自动换行
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        //5、创建Result对象，将Result对象加载到TransHandler中
        //注意：1、这一步必须在Transformer.setOutputProperty()之后，不然设置的xml属性将不生效
        //	  2、这一步也必须在TransformerHandler.startDocument()之前，不然会报错。
        //		 分析源码后发现，startDocument()会先判断result是否为空，为空则报错
        StreamResult result = new StreamResult(new StringWriter());
        handler.setResult(result);
        //6、创建属性Attribute对象
        AttributesImpl attr = new AttributesImpl();
        //7、开始写文件
        handler.startDocument();
        //8、写入根节点bookstore
        handler.startElement("", "", "dataset", attr);
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取IoC容器中JdbcTemplate实例
        JdbcTemplate jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
        for (String table : tables) {
            if ("".equals(table)) {
                continue;
            }
            String sql = String.format("select * from %s", table);
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
            for (Map<String, Object> map : maps) {
                //清空属性，每次新增一个节点都需要先清空一下属性，防止在设置节点属性时发生错误
                attr.clear();
                addMapAtt(map, attr);
                handler.startElement("", "", table, attr);
                handler.endElement("", "", table);
            }
        }
        //16、写入根节点末尾
        handler.endElement("", "", "dataset");
        //17、写文件结束
        handler.endDocument();
        System.out.println(result.getWriter().toString());
    }

    private static void addMapAtt(Map<String, Object> map, AttributesImpl attr) {
        for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
            String key = stringObjectEntry.getKey();
            Object value = stringObjectEntry.getValue();
            boolean ignore = value == null
                    || "lastUpdateTime".equals(key)
                    || "createTime".equals(key);
            if (ignore) {
                continue;
            }
            attr.addAttribute("", "", key, "", value.toString());
        }
    }
}
